/* 

==========================================================

DX490a - Summer 2010

Instructor: Stelios Manousakis

==========================================================

Class 7.2:

A ProcMod & control mapping example

Contents:

• A sound example

==========================================================

*/


// ================= PROCMOD WITH HID CONTROL =================


// This example builds on example 7.1. The synthdef has been converted to a procmod, and a SpaceNavigator device is used to control the sound. The buttons turn the procmod on and off, and the 6 axes control various aspects of the synthesis.


(

// === • Interfacing connections: ===

// The first thing you need to do is look at the devices that are connected to your machine:

GeneralHID.buildDeviceList;

// You can make a list of the devices:

d = GeneralHID.deviceList;

// You then can pick a specific device  and open it for usage:

a = GeneralHID.open(d[2]); // maybe you'd need to change that...

//// start the eventloop if its not running already:

GeneralHID.startEventLoop;

//a.debug_(false)


// === • Sound synthesis ===

// load a simple FM synth, no mapping inside the synth

~combfm = CtkSynthDef( \combFM, { |outbus = 0, freq = 440, harm = 1, modix = 1, delay = 0.1, pan = 0, amp = 0.5, envbus, freqMul = 1|

var car, mod, out, dev, modfreq;

freq = freq * freqMul;

modfreq = freq * harm;

dev = modix * modfreq;

mod = SinOsc.ar(modfreq, 0, dev);

car = SinOsc.ar(freq + (mod * modix));

out = Out.ar(outbus, (Pan2.ar(CombC.ar(car, 0.5, delay, 0.5), pan, amp) * In.kr(envbus)));
});

/// === • mapping stuff ===


// create as many control buses as the parameters of the controlling interface

~ctrl = 6.collect({CtkControl.play});


// create some envelopes to handle the parameter mapping as you wish

~panEnv = Env([-1, 1], [1], \lin);

~ampEnv = Env([0.001, 0.7], [1], 3);

~modEnv = Env([1, 50], [1], 2);

~freqEnv = Env([40, 3000], [1], 4);

//~cutEnv = Env([50, 8000], [1], 2);

~delEnv = Env([0, 0.5], [1], 2);

~harmEnv = Env([0.1, 10], [1], 2);


// Name the device's controls:

a.add(\leftBtn, [1, 1]);

a.add(\rightBtn, [1, 2]);

a.add(\r_l_pan, [3, 48]);

a.add(\u_d_pan, [3, 49]);

a.add(\push_pull, [3, 50]);

a.add(\tilt, [3, 51]);

a.add(\spin, [3, 52]);

a.add(\roll, [3, 53]);


// within each slot's action: fill the appropriate CtkControl bus with the values coming in from the device slot:

a[\r_l_pan].action_({|val| ~ctrl[0].set([~panEnv[val.value]])});

a[\u_d_pan].action_({|val| ~ctrl[1].set([~modEnv[val.value]])});

a[\push_pull].action_({|val| ~ctrl[2].set([~ampEnv[val.value]])});

a[\tilt].action_({|val| ~ctrl[3].set([~delEnv[val.value]])});

a[\spin].action_({|val| ~ctrl[4].set([~freqEnv[val.value]])});

a[\roll].action_({|val| ~ctrl[5].set([~harmEnv[val.value]])});


// use the buttons to turn on/off the procmod

a[\leftBtn].action_({|val| if(val.value == 1, {p.play; q.release})}); // left button starts the procmod

a[\rightBtn].action_({|val| if(val.value == 1, {q.play; p.release})}); // right button stops it



// === • the procmod ===

p = ProcMod.new(Env([0, 1, 0], [0.1, 3], \sin, 1), id: \testHID, server: s)

.function_({arg group, envbus, server;

var note;

note = ~combfm.new(target:group)

.freqMul_(1)

.pan_(~ctrl[0]).modix_(~ctrl[1]).amp_(~ctrl[2]).delay_(~ctrl[3]).freq_(~ctrl[4]).harm_(~ctrl[5])

.envbus_(envbus).play;

});



// === • the procmod ===

q = ProcMod.new(Env([0, 1, 0], [0.1, 3], \sin, 1), id: \testHID, server: s)

.function_({arg group, envbus, server;

var note;

note = ~combfm.new(target:group)

.freqMul_(0.1)

.pan_(~ctrl[0]).modix_(~ctrl[1]).amp_(~ctrl[2]).delay_(~ctrl[3]).freq_(~ctrl[4]).harm_(~ctrl[5])

.envbus_(envbus).play;

});

)




/*

LAB: Make one or more procmods with your own synthdefs, and control them in real-time with a device

*/